<template>
  <div class="video-fallback-container">
    <div v-if="error" class="error-panel">
      <div class="error-icon">⚠️</div>
      <h3>视频加载失败</h3>
      <p class="error-message">{{ errorMessage }}</p>
      
      <div class="error-details" v-if="showDetails">
        <p><strong>错误类型:</strong> {{ error.type }}</p>
        <p><strong>错误代码:</strong> {{ error.code }}</p>
        <p><strong>URL:</strong> {{ src }}</p>
      </div>
      
      <div class="solutions">
        <h4>解决方案:</h4>
        <ul>
          <li v-for="solution in solutions" :key="solution.id">
            {{ solution.text }}
          </li>
        </ul>
      </div>
      
      <div class="actions">
        <button @click="retry" class="retry-btn">重试</button>
        <button @click="toggleDetails" class="details-btn">
          {{ showDetails ? '隐藏详情' : '显示详情' }}
        </button>
        <button @click="testNetwork" class="test-btn">测试网络</button>
      </div>
    </div>
    
    <div v-else-if="loading" class="loading-panel">
      <div class="loading-spinner"></div>
      <p>正在加载视频...</p>
    </div>
    
    <div v-else class="video-container">
      <video
        ref="videoPlayer"
        class="video-js vjs-default-skin"
        controls
        preload="auto"
        :width="width"
        :height="height"
        :poster="poster"
      >
        <source v-for="source in processedSources" :key="source.src" :src="source.src" :type="source.type" />
        <p class="vjs-no-js">
          您的浏览器不支持HTML5视频播放。
          <a :href="src" target="_blank">下载视频</a>
        </p>
      </video>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, computed, watch } from 'vue'

const props = defineProps({
  src: {
    type: String,
    required: true
  },
  width: {
    type: [String, Number],
    default: 640
  },
  height: {
    type: [String, Number],
    default: 360
  },
  poster: {
    type: String,
    default: ''
  },
  autoplay: {
    type: Boolean,
    default: false
  },
  type: {
    type: String,
    default: 'video/mp4'
  }
})

const emit = defineEmits(['ready', 'error', 'loaded'])

// 状态管理
const error = ref(null)
const loading = ref(true)
const showDetails = ref(false)
const player = ref(null)

// 错误处理
const errorMessage = computed(() => {
  if (!error.value) return ''
  
  switch (error.value.code) {
    case 1:
      return '视频加载被中止'
    case 2:
      return '网络错误：无法连接到视频服务器'
    case 3:
      return '视频解码错误：格式不支持'
    case 4:
      return '视频格式不支持'
    default:
      return '未知错误'
  }
})

// 解决方案
const solutions = computed(() => {
  if (!error.value) return []
  
  const baseSolutions = [
    { id: 1, text: '检查网络连接是否正常' },
    { id: 2, text: '刷新页面重试' },
    { id: 3, text: '联系技术支持' }
  ]
  
  if (error.value.code === 2) {
    return [
      { id: 1, text: '检查视频服务器是否运行正常' },
      { id: 2, text: '确认视频URL是否正确' },
      { id: 3, text: '检查防火墙设置' },
      ...baseSolutions.slice(2)
    ]
  }
  
  return baseSolutions
})

// 处理视频源
const processedSources = computed(() => {
  const sources = []
  
  if (props.src.includes('.m3u8')) {
    sources.push({
      src: props.src,
      type: 'application/x-mpegURL'
    })
  } else if (props.src.includes('.mp4')) {
    sources.push({
      src: props.src,
      type: 'video/mp4'
    })
  } else {
    sources.push({
      src: props.src,
      type: props.type
    })
  }
  
  return sources
})

// 方法
const initializePlayer = () => {
  if (!props.src) {
    handleError({ code: 4, type: 'src_missing' })
    return
  }
  
  loading.value = true
  error.value = null
  
  // 测试URL可访问性
  testUrlAvailability(props.src)
    .then(available => {
      if (available) {
        loadVideo()
      } else {
        handleError({ code: 2, type: 'network_error' })
      }
    })
    .catch(() => {
      handleError({ code: 2, type: 'network_error' })
    })
}

const testUrlAvailability = async (url) => {
  try {
    const response = await fetch(url, { method: 'HEAD' })
    return response.ok
  } catch {
    return false
  }
}

const loadVideo = () => {
  const video = document.createElement('video')
  video.src = props.src
  
  video.addEventListener('loadeddata', () => {
    loading.value = false
    emit('loaded')
  })
  
  video.addEventListener('error', (e) => {
    handleError({
      code: video.error?.code || 4,
      type: 'media_error',
      message: video.error?.message
    })
  })
  
  video.addEventListener('loadstart', () => {
    loading.value = true
  })
  
  video.load()
}

const handleError = (errorInfo) => {
  error.value = errorInfo
  loading.value = false
  emit('error', errorInfo)
  
  console.error('视频加载失败:', {
    url: props.src,
    error: errorInfo,
    timestamp: new Date().toISOString()
  })
}

const retry = () => {
  error.value = null
  loading.value = true
  initializePlayer()
}

const toggleDetails = () => {
  showDetails.value = !showDetails.value
}

const testNetwork = async () => {
  const url = props.src
  try {
    const response = await fetch(url, { method: 'HEAD' })
    alert(`网络测试结果:\nURL: ${url}\n状态: ${response.status}\n可用: ${response.ok ? '是' : '否'}`)
  } catch (error) {
    alert(`网络测试失败:\nURL: ${url}\n错误: ${error.message}`)
  }
}

// 生命周期
onMounted(() => {
  initializePlayer()
})

watch(() => props.src, () => {
  initializePlayer()
})
</script>

<style scoped>
.video-fallback-container {
  position: relative;
  width: 100%;
  height: 100%;
}

.error-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px;
  text-align: center;
  background: #f8f9fa;
  border-radius: 8px;
  min-height: 300px;
}

.error-icon {
  font-size: 48px;
  margin-bottom: 16px;
}

.error-panel h3 {
  color: #dc3545;
  margin-bottom: 8px;
}

.error-message {
  color: #6c757d;
  margin-bottom: 16px;
}

.error-details {
  background: white;
  padding: 16px;
  border-radius: 4px;
  margin: 16px 0;
  text-align: left;
  font-size: 14px;
}

.solutions {
  margin: 16px 0;
  text-align: left;
}

.solutions ul {
  margin: 8px 0;
  padding-left: 20px;
}

.actions {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: center;
}

.retry-btn, .details-btn, .test-btn {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
}

.retry-btn {
  background: #007bff;
  color: white;
}

.details-btn {
  background: #6c757d;
  color: white;
}

.test-btn {
  background: #28a745;
  color: white;
}

.loading-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 300px;
}

.loading-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #f3f3f3;
  border-top: 4px solid #007bff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.video-container {
  width: 100%;
  height: 100%;
}

.vjs-no-js {
  padding: 20px;
  text-align: center;
}
</style>